package ch.sv7.tool.dbmanager.db.ant;

import org.apache.tools.ant.BuildException;

import ch.sv7.tool.dbmanager.DbManagerException;
import ch.sv7.tool.dbmanager.db.DatabaseSchema;
import ch.sv7.tool.dbmanager.db.difference.SchemaDifferences;
import ch.sv7.tool.dbmanager.db.xml.XmlDatabaseSchemaFactory;
import ch.sv7.tool.log.AntAppender;
import ch.sv7.tool.log.Appender;
import ch.sv7.tool.log.Logger;

public class CompareSchemaTask extends TablesSqlTask {

	private String filename;
	private boolean failOnDifferences = true;

	public CompareSchemaTask() {
		Logger.setAppender(new AntAppender(this, Appender.LEVEL_INFO));
	}

	public void execute() throws BuildException {
		try {
			java.sql.Connection conn = getConnection();
			try {
				log("Extracting schema info");
				XmlDatabaseSchemaFactory xmlFactory = new XmlDatabaseSchemaFactory(filename, getSchema());
				DatabaseSchema xmlSchema = xmlFactory.getDatabaseSchema(getTables());
				DatabaseSchema jdbcDbSchema = getDatabaseSchema(conn, getTables());
				
				SchemaDifferences differences = new SchemaDifferences();
				xmlSchema.computeDifferencesFromActual(differences, jdbcDbSchema);
				
				differences.dump(System.out);
				if (differences.hasBlockingDifferences())  {
					if (failOnDifferences){
						throw new BuildException("Incompatible database ! " + differences.getBlockingDifferencesSize() + " incompatibility(ies) found", getLocation());
					} else {
						log("There is schema difference between reference and actual DB ! " + differences.getBlockingDifferencesSize() + " difference(s) found");
					}					
				} else {
					log("Database is compatible with torque scripts !");
				}
				
			} catch (BuildException e) {
				throw e;
			} catch (DbManagerException e) {
				throw new BuildException(e, getLocation());
			} catch (Exception e) {
				e.printStackTrace();
				throw new BuildException(e, getLocation());
			} finally {
				closeConnection(conn);
			}
		} catch (DbManagerException e) {
			throw new BuildException(e, getLocation());
		}
	}

	public String getFilename() {
		return filename;
	}

	public void setFilename(String string) {
		filename = string;
	}

	/**
	 * @return the failOnDifferences
	 */
	public boolean isFailOnDifferences() {
		return failOnDifferences;
	}

	/**
	 * @param failOnDifferences the failOnDifferences to set
	 */
	public void setFailOnDifferences(boolean failOnDifferences) {
		this.failOnDifferences = failOnDifferences;
	}
	
	
}
